package net.tv90.volunteerserveradmin.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import net.tv90.volunteerserveradmin.annotation.OptLogger;
import net.tv90.volunteerserveradmin.constant.OptLoggerConstant;
import net.tv90.volunteerserveradmin.constant.RoleConstant;
import net.tv90.volunteerserveradmin.exception.ServiceException;
import net.tv90.volunteerserveradmin.model.dto.StudentDTO;
import net.tv90.volunteerserveradmin.model.dto.StudentQueryDTO;
import net.tv90.volunteerserveradmin.model.vo.StudentVO;
import net.tv90.volunteerserveradmin.service.StudentService;
import net.tv90.volunteerserveradmin.utils.CsvUtils;
import net.tv90.volunteerserveradmin.utils.entity.PageResult;
import net.tv90.volunteerserveradmin.utils.entity.Result;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.List;

@Validated
@CrossOrigin
@RestController
@RequestMapping("student")
@Tag(name = "学生管理接口")
public class StudentController {

    @Resource
    private StudentService studentService;

    @GetMapping("/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.QUERY)
    @Operation(summary = "获取学生信息", description = "根据学生ID获取学生详细信息")
    public Result<StudentVO> getStudentById(@PathVariable Long id) {
        return Result.success(studentService.getStudentById(id));
    }

    @GetMapping("/self/{id}")
    @SaCheckRole(RoleConstant.STUDENT)
    @OptLogger(OptLoggerConstant.QUERY)
    @Operation(summary = "学生获取自己的信息", description = "学生根据自己的ID获取学生详细信息")
    public Result<StudentVO> getStudentSelfById(@PathVariable Long id) {
        return Result.success(studentService.getStudentSelfById(id));
    }

    @GetMapping("/all")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.QUERY)
    @Operation(summary = "获取所有学生", description = "获取所有学生的简要信息")
    public Result<List<StudentVO>> getAllStudents() {
        return Result.success(studentService.getAllStudents());
    }

    @PostMapping("/add")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.ADD)
    @Operation(summary = "添加学生", description = "添加新的学生信息")
    public Result<Void> addStudent(@RequestBody StudentDTO studentDTO) {
        studentService.addStudent(studentDTO);
        return Result.success();
    }

    @PutMapping("/update/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.UPDATE)
    @Operation(summary = "更新学生信息", description = "根据学生ID更新学生信息")
    public Result<Void> updateStudent(@PathVariable Long id, @RequestBody StudentDTO studentDTO) {
        studentService.updateStudent(id, studentDTO);
        return Result.success();
    }

    @DeleteMapping("/delete/{id}")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.DELETE)
    @Operation(summary = "删除学生", description = "根据学生ID删除学生")
    public Result<Void> deleteStudent(@PathVariable Long id) {
        studentService.deleteStudent(id);
        return Result.success();
    }

    @PostMapping("/query")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.QUERY)
    @Operation(summary = "查询学生信息", description = "复杂查询获取学生详细信息")
    public Result<PageResult<StudentVO>> queryStudent(@RequestBody StudentQueryDTO dto) {
        return Result.success(studentService.queryStudent(dto));
    }

    @GetMapping("/export")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.QUERY)
    @Operation(summary = "导出学生信息", description = "导出所有学生信息为CSV文件")
    public void exportStudentsToCSV(HttpServletResponse response) throws IOException {
        response.setContentType("text/csv;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=students.csv");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<StudentVO> students = studentService.getAllStudents();
        PrintWriter writer = response.getWriter();
        writer.write('\uFEFF');
        writer.println("学号,姓名,性别,专业,入学年份,身份证号,班级,出生日期,地址,用户名,邮箱");
        for (StudentVO student : students) {
            String studentNumber = CsvUtils.escapeCsvField(student.getStudentNumber());
            String name = CsvUtils.escapeCsvField(student.getName());
            String gender = CsvUtils.escapeCsvField(student.getGender());
            String major = CsvUtils.escapeCsvField(student.getMajor());
            String enrollmentYear = CsvUtils.escapeCsvField(student.getEnrollmentYear().toString());
            String idCardNumber = CsvUtils.escapeCsvField(student.getIdCardNumber());
            String studentClass = CsvUtils.escapeCsvField(student.getStudentClass());
            String dateOfBirth = CsvUtils.escapeCsvField(sdf.format(student.getDateOfBirth()));
            String address = CsvUtils.escapeCsvField(student.getAddress());
            String userName = CsvUtils.escapeCsvField(student.getUserName());
            String email = CsvUtils.escapeCsvField(student.getEmail());
            StringBuilder sb = new StringBuilder();
            sb.append(studentNumber).append(",");
            sb.append(name).append(",");
            sb.append(gender).append(",");
            sb.append(major).append(",");
            sb.append(enrollmentYear).append(",");
            sb.append(idCardNumber).append(",");
            sb.append(studentClass).append(",");
            sb.append(dateOfBirth).append(",");
            sb.append(address).append(",");
            sb.append(userName).append(",");
            sb.append(email);
            writer.println(sb);
        }
        writer.flush();
    }

    @PostMapping("/import")
    @SaCheckRole(RoleConstant.ADMIN)
    @OptLogger(OptLoggerConstant.ADD)
    @Operation(summary = "批量导入学生信息", description = "从CSV文件批量导入学生信息")
    public Result<Void> importStudentsFromCSV(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return Result.failed("文件不能为空");
        }
        try (InputStream inputStream = file.getInputStream()) {
            CsvMapper csvMapper = new CsvMapper();
            CsvSchema schema = CsvSchema.builder()
                    .addColumn("studentNumber")
                    .addColumn("name")
                    .addColumn("gender")
                    .addColumn("major")
                    .addColumn("enrollmentYear")
                    .addColumn("idCardNumber")
                    .addColumn("studentClass")
                    .addColumn("dateOfBirth")
                    .addColumn("address")
                    .setUseHeader(true) // 表示第一行是表头
                    .build();
            MappingIterator<StudentDTO> iterator = csvMapper
                    .readerFor(StudentDTO.class)
                    .with(schema)
                    .readValues(inputStream);
            List<StudentDTO> dtoList = iterator.readAll();
            studentService.batchAddStudents(dtoList);
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        return Result.success();
    }

}
